package org.chen.aao.ai.service;

import org.chen.aao.common.ai.dto.*;
import org.chen.aao.ai.feign.SubsServiceClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@RequiredArgsConstructor
public class AIService {

    private final RedisTemplate<String, Object> redisTemplate;
    private final SubsServiceClient subsServiceClient;

    // 获取使用统计
    public UsageStatsResponse getUsageStats(Long userId) {
        LocalDate today = LocalDate.now();
        String todayKey = String.format("usage:daily:%d:%s", userId, today);
        String monthKey = String.format("usage:monthly:%d:%s", userId, today.withDayOfMonth(1));

        // 获取今日使用量
        Map<Object, Object> todayUsage = redisTemplate.opsForHash().entries(todayKey);

        // 获取本月使用量
        Map<Object, Object> monthUsage = redisTemplate.opsForHash().entries(monthKey);

        // 获取用户限制
        String subscriptionLevel = getSubscriptionLevel(userId);

        return UsageStatsResponse.builder()
                .daily(UsageStatsResponse.DailyUsage.builder()
                        .chatCount(getIntValue(todayUsage, "chat"))
                        .translationCount(getIntValue(todayUsage, "translation"))
                        .voiceCount(getIntValue(todayUsage, "voice"))
                        .totalTokens(getIntValue(todayUsage, "tokens"))
                        .build())
                .monthly(UsageStatsResponse.MonthlyUsage.builder()
                        .chatCount(getIntValue(monthUsage, "chat"))
                        .translationCount(getIntValue(monthUsage, "translation"))
                        .voiceCount(getIntValue(monthUsage, "voice"))
                        .totalTokens(getLongValue(monthUsage, "tokens"))
                        .estimatedCost(calculateCost(getLongValue(monthUsage, "tokens")))
                        .build())
                .limits(UsageStatsResponse.Limits.builder()
                        .dailyChatLimit(getMaxDailyChats(userId))
                        .dailyTranslationLimit(getMaxDailyTranslations(userId))
                        .dailyVoiceLimit(getMaxDailyVoiceToText(subscriptionLevel))
                        .build())
                .build();
    }

    // 获取订阅等级
    private String getSubscriptionLevel(Long userId) {
        String cacheKey = "user:subscription:" + userId;
        String level = (String) redisTemplate.opsForValue().get(cacheKey);
        if (level == null) {
            level = subsServiceClient.getSubscriptionStatusById(userId).getData().getPlan();
            redisTemplate.opsForValue().set(cacheKey, level, 1, TimeUnit.HOURS);
        }
        return level;
    }

    // 获取用户配额限制
    private int getMaxDailyChats(Long userId) {
        // 根据用户订阅等级返回不同配额
        String subscriptionLevel = getSubscriptionLevel(userId);
        return switch (subscriptionLevel) {
            case "PREMIUM" -> 1000;
            case "BASIC" -> 100;
            default -> 10;
        };
    }

    private int getMaxDailyTranslations(Long userId) {
        return getMaxDailyTranslationsById(getSubscriptionLevel(userId));
    }

    private int getMaxDailyTranslationsById(String subscriptionLevel) {
        return switch (subscriptionLevel) {
            case "PREMIUM" -> 2000;
            case "BASIC" -> 200;
            default -> 20;
        };
    }

    private int getMaxDailyVoiceToText(String subscriptionLevel) {
        return switch (subscriptionLevel) {
            case "PREMIUM" -> 500;
            case "BASIC" -> 50;
            default -> 5;
        };
    }

    // 计算成本
    private Double calculateCost(Long tokens) {
        // 假设每1000个token成本为0.002美元，约0.014人民币
        return tokens * 0.000014;
    }

    // 工具方法
    private Integer getIntValue(Map<Object, Object> map, String key) {
        Object value = map.get(key);
        if (value instanceof Integer) {
            return (Integer) value;
        } else if (value instanceof String) {
            try {
                return Integer.parseInt((String) value);
            } catch (NumberFormatException e) {
                return 0;
            }
        }
        return 0;
    }

    private Long getLongValue(Map<Object, Object> map, String key) {
        Object value = map.get(key);
        if (value instanceof Long) {
            return (Long) value;
        } else if (value instanceof Integer) {
            return ((Integer) value).longValue();
        } else if (value instanceof String) {
            try {
                return Long.parseLong((String) value);
            } catch (NumberFormatException e) {
                return 0L;
            }
        }
        return 0L;
    }
}
